package com.opencvjava.lessons.imgproc;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Service;

import static com.opencvjava.support.util.CvUtils.imshow;
import static com.opencvjava.support.util.CvUtils.mat;
import static org.opencv.imgproc.Imgproc.remap;

@Service
public class L15_Remap {
    private Mat mapX;
    private Mat mapY;
    private Mat dst;
    private int ind = 0;

    public void test() {
        Mat src = mat("lena.jpg");
        if (src.empty()) {
            throw new RuntimeException("图片读取失败");
        }
        mapX = new Mat(src.size(), CvType.CV_32F);
        mapY = new Mat(src.size(), CvType.CV_32F);
        dst = new Mat();
        for (; ; ) {
            try {
                Thread.sleep(2000);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
            updateMap();
            remap(src, dst, mapX, mapY, Imgproc.INTER_LINEAR);
            imshow("Remap demo", dst);
        }
    }

    private void updateMap() {
        float buffX[] = new float[(int) (mapX.total() * mapX.channels())];
        mapX.get(0, 0, buffX);
        float buffY[] = new float[(int) (mapY.total() * mapY.channels())];
        mapY.get(0, 0, buffY);
        int rows = mapX.rows();
        int cols = mapX.cols();
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                switch (ind) {
                    case 0:
                        if (j > cols * 0.25 && j < cols * 0.75 && i > rows * 0.25 && i < rows * 0.75) {
                            buffX[i * cols + j] = 2 * (j - cols * 0.25f) + 0.5f;
                            buffY[i * cols + j] = 2 * (i - rows * 0.25f) + 0.5f;
                        } else {
                            buffX[i * cols + j] = 0;
                            buffY[i * cols + j] = 0;
                        }
                        break;
                    case 1:
                        buffX[i * cols + j] = j;
                        buffY[i * cols + j] = rows - i;
                        break;
                    case 2:
                        buffX[i * cols + j] = cols - j;
                        buffY[i * cols + j] = i;
                        break;
                    case 3:
                        buffX[i * cols + j] = cols - j;
                        buffY[i * cols + j] = rows - i;
                        break;
                    default:
                        break;
                }
            }
        }
        mapX.put(0, 0, buffX);
        mapY.put(0, 0, buffY);
        ind = (ind + 1) % 4;
    }
}
